//gW 2010-02-17   'View'            tab=3

   /*  viewitem = *(viewtyp ":" viewvalue *("," viewvalue) ;)
    *     
    *      viewtyp = *("SUMMARY" / "CATEGORIES" / "NOTES" / "LOCATION") | ("DATE") 
    *         Note:  "DESCRIPTION" has to be replaced with "summary" 
    *         
    *      'viewtyp' other than 'DATE' MAY occur more than once;
    *    for each 'viewtyp' one 'viewvalue' MUST occur at least once, 
    *    but MAY occur more than once
    *
    *    For each reminder the items are checked against the 'viewitem'. 
    *    If the condition is met, the reminder is included in the 'View' list.
    *
    *    For 'viewtyp' = "DATE"  valid entries to 'viewvalue' are:
    *       'viewvalue' = *('TODAY'/'CURRENT_WEEK'/'NEXT_WEEK'/'NEXT_2WEEKS'/'CURRENT_MONTH' ),
    *       the reminder date has to fall within the 'viewvalue' range; all date ranges
    *         are related to 'today'.
    *
    *    For 'viewtype' = *("SUMMARY" / "CATEGORIES" / "NOTES" / "LOCATION")
    *       the 'viewvalue' string MUST exist in the reminder item.
    *
    *       'viewvalue' with leading '#' character will invert the condition
    *          the 'viewvalue' string MUST NOT exist in the reminder item.
    *
    *    Multiple 'viewvalue' for one 'viewtyp' are handled as 'OR' connected,
    *    multiple 'viewtyp' for one 'viewitem' are handled as 'AND' function.
    *
    *        Example:  "DESCRIPTION:Mail,Send;CATEGORIES:business;categories:projectA;"
    *         read:  'mail' OR 'send' in 'DESCRIPTION' AND CATEGORIES='business' AND CATEGORIES='projectA'
    *
    *   'Criteria' descriptors
    *       The 'viewtyp' (called 'Criteria' at UI level) is stored to a preference:
    *          'extensions.reminderFox.views'
    *       with 'general' descriptors. At the UI those descriptors have 'local'
    *       equivalent stored with "reminderFox-bundle" / reminderfox.properties.
    *
    *       Example:  general: "LOCATION:Hamburg", local: "Ort:Hambug" 
    **/

/**
     *    For 'viewtyp' = "DATE"  valid entries to 'viewvalue' are:
     *      "DATE:viewvalue1 (","viewvalue2);)
     * 
     *      The general 'viewvalueX' is:
     *      'viewvalueX' = {num}{D|M|Y}
     *          {num} is the count for days, months, or years, 
     *              if positiv date is in future, negative in the past 
     *          'D' is days, 'M' is month, 'Y' is year, only one value allowed
     *
     *          'viewvalue2' (optional)
     *          if 'viewvalue2' is obmitted 'viewvalue1' is related to 'today'
     *          if 'viewvalue1' > 'viewvalue2' the values are exchanged
     *      
     *  Special case for 'viewvalue1'   (**compatibility with previous version**)
     *    if one of the following definition matches 'viewvalue2' is ignored
     * 
     *    'viewvalue1' = *('TODAY'/'CURRENT_WEEK'/'CURRENT_MONTH'/'CURRENT_YEAR')
     *      and 
     *    'viewvalue1' = *('NEXT_WEEK'/'NEXT_2WEEKS')   
     *        these values are deprecated but supported to be compatible with
     *        prev version.
     *        Instead use new definition 'xD', eg.: 
     *           'NEXT_WEEK' -->  '7D',   'NEXT_2WEEKS' -->  '14D'
     *        or 'NEXT_WEEK' -->  '-7D,7D'  which looks into past and furture 
     *            7 days giving a span of 7days + today + 7days
     *
     * Examples with 'today' as of 'Jan 05 2010':
     *   
     *  -90D    -->Wed Oct 07 2009 00:00:00 GMT+0200 Tue Jan 05 2010 13:11:51 GMT+0100
     *  10D,40D -->Fri Jan 15 2010 00:00:00 GMT+0100 Sun Feb 14 2010 00:00:00 GMT+0100
     *  -1M,2M  -->Sat Dec 05 2009 00:00:00 GMT+0100 Fri Mar 05 2010 00:00:00 GMT+0100
     *  3M      -->Tue Jan 05 2010 13:13:59 GMT+0100 Mon Apr 05 2010 00:00:00 GMT+0200
     *  120D,1M -->Fri Feb 05 2010 00:00:00 GMT+0100 Wed May 05 2010 00:00:00 GMT+0200
     *  TODAY   -->Tue Jan 05 2010 00:00:00 GMT+0100 Tue Jan 05 2010 00:00:00 GMT+0100     
     *  CURRENT_MONTH -->Fri Jan 01 2010 00:00:00 GMT+0100 Sun Jan 31 2010 00:00:00 GMT+0100
     * 
*/
    
   // strings to hold 'locale' descriptors for 'Criteria' and 'Date'
   var sViewLocalDesc  = reminderFox_getBundle().getString("rf.html.heading.description");
   var sViewLocalCat   = reminderFox_getBundle().getString("rf.add.reminders.tooltip.categories");
   var sViewLocalNotes = reminderFox_getBundle().getString("rf.add.mail.message.notes");
   var sViewLocalLoc   = reminderFox_getBundle().getString("rf.add.reminders.tooltip.locaton");
   var sViewLocalDate  = reminderFox_getBundle().getString("rf.html.heading.date");

   var sViewToday      = reminderFox_getBundle().getString("rf.views.heute");        //0: "Heute"         "TODAY"
   var sViewCurWeek    = reminderFox_getBundle().getString("rf.views.currentweek");  //1: "Diese Woche"   "CURRENT_WEEK"
   var sViewCurMonth   = reminderFox_getBundle().getString("rf.views.currentmonth"); //2: "Dieser Monat"  "CURRENT_MONTH"
   var sViewCurYear    = reminderFox_getBundle().getString("rf.views.currentyear");  //3: "Dieses Jahr"   "CURRENT_YEAR"

   var sViewNextWeek    = reminderFox_getBundle().getString("rf.views.nextweek.label"); // "Naechste Woche"  "NEXT_WEEK"
   var sViewNext2Weeks  = reminderFox_getBundle().getString("rf.views.next2weeks");     // "2Wochen"        "NEXT_2WEEKS"

   var sViewSortUp       = reminderFox_getBundle().getString("rf.views.sorter.viewUp"); 
   var sViewSortDn       = reminderFox_getBundle().getString("rf.views.sorter.viewDown"); 
   var sCriteriaSortUp   = reminderFox_getBundle().getString("rf.views.sorter.criteriaUp"); 
   var sCriteriaSortDn   = reminderFox_getBundle().getString("rf.views.sorter.criteriaDown");  
   var sValidNameString  = reminderFox_getBundle().getString("rf.views.criteria.notvalidString") + ":  ; : > <";

   var sViewDateAlreadydefined =  reminderFox_getBundle().getString("rf.views.date.alreadydefined");

   var sViewsNew         = reminderFox_getBundle().getString("rf.views.new");        // new
   var sViewsNewTitel    = reminderFox_getBundle().getString("rf.views.newView");    // New 'View'
   var sViewsNewInstruct = reminderFox_getBundle().getString("rf.views.enterName");  // Enter the new 'View' name:

   var stttCriteria      = reminderFox_getBundle().getString("rf.views.ttt.criteria");  // "Select a 'Criteria' to edit"
   var stttEdit          = reminderFox_getBundle().getString("rf.views.ttt.edit");      //  "Edit 'View's"
   var stttEditor        = reminderFox_getBundle().getString("rf.views.ttt.editor");
   var sViewsExportSend  = reminderFox_getBundle().getString("rf.views.editor.exportSend");
   var sViewsName        = reminderFox_getBundle().getString("rf.views.name");

   var sViewsChange      = reminderFox_getBundle().getString("rf.views.change");
   var sViewsEdit        = reminderFox_getBundle().getString("rf.views.edit");
   var sViewsAdd         = reminderFox_getBundle().getString("rf.views.add");
   
   var sRmFxTitel        = reminderFox_getBundle().getString("rf.title");  //use .properties 
        

   var gRmFx_Views = {
       Pref      : "", 
       Label     : {},      /* .Label and .Items corresponded with each other and */ 
       Items     : {},      /*    hold all View definitions */
       cPrefs    : "",
       cLabel    : { Event: "", Todo: "" },     /* .cXX  is the current    */
       cItems    : { Event: "", Todo: "" },     /*   selected View   */
       cDateSpan : { start: null, end: null }
    };

  var aViewEditorChanged      = false;
  var aViewEditor2Save        = false;


// === main function to pre-select reminder based of 'VIEW' selection === 
function rmFx_ViewThis(reminder, isRemindersOrTodosString) {
  var mode = (isRemindersOrTodosString == "reminders"  || 
  	(isRemindersOrTodosString != "todos" && isReminderTabSelected()))  ? "Event" : "Todo";
  var dmode = (isRemindersOrTodosString == "reminders"  || 
  	(isRemindersOrTodosString != "todos" && isReminderTabSelected()))  ? "" : "Todo";
  
  gRmFx_Views.cDateSpan.start = null;
  gRmFx_Views.cDateSpan.end = null;
  
  if (document.getElementById("displayType" + dmode).selectedIndex < 8) return true;
  if (gRmFx_Views.cItems[mode] == "") return true;  // no view for TAB !

  var statusString = true;
  var statusStringALL  = true;
        
  //  if definition doesn't has DATE item, set it TRUE
  var statusDate = (gRmFx_Views.cItems[mode].search(/DATE:/) == -1) ? true : false;
   var viewArray = gRmFx_Views.cItems[mode].split(";")
   
   for (var i=0; i < viewArray.length ; i++) {
      var viewvalueInvert = false;   // for checking "NOT" included string

      var viewtyp = viewArray[i].split(":")[0].toLowerCase();   //  like Summary, Category, Date
      var viewvalue = viewArray[i].split(":")[1];   // value: like "Birthday"
      if (reminder[viewtyp] == null ) {
         statusStringALL = false;
      } else {
			
		 // tfm : this is way too complex to read/debug.  Should rewrite to make it readable, like:
		 // if ( view.criteria.type == Summary ) { if ( reminder.summary == view.criteria.value ) ...
         if ((viewtyp != null) || (viewtyp != "")) {

            if (viewtyp == 'date') {    //  (" check the 'date' value of reminder");
               rmFx_View.vDateSpan(viewvalue);

               var limitWeeklyReminders = false;   
               var statusDate = (reminderFox_getAllRemindersInDateRange
                     (reminder, gRmFx_Views.cDateSpan.start, gRmFx_Views.cDateSpan.end, limitWeeklyReminders)
                    .length > 0) ? true : false;   
                    
            } else {                    //  (" check string values");
               var statusString = false;
                                            
               var viewdetail = viewvalue.split(",")
               for (var j1=0; j1 < viewdetail.length ; j1++) {
               
                  var cViewDetail = viewdetail[j1];
                  if (cViewDetail[0] == "#") {
                     viewvalueInvert = true;
                     cViewDetail = cViewDetail.substring(1,viewvalue.length)
                  }
                  if (viewvalueInvert == true) {  //  if cViewDetail NOT included
                     if (reminder[viewtyp].toLowerCase().indexOf(cViewDetail.toLowerCase()) == -1){
                        statusString = true;
                     }
                   } else {     //  if cViewDetail IS  included
                     if (reminder[viewtyp].toLowerCase().indexOf(cViewDetail.toLowerCase()) != -1){
                        statusString = true;
                     }
                  }
              }// for viewdetail
            } // string
            statusStringALL = statusStringALL && statusString;
         } //viewtype # null
      } // reminder[]
   } // viewarry
   return (statusDate && statusStringALL && statusString);
}

////// 'View'  functions ///////////////////////////////////////////////////////
function rmFx_View () { 
}


//=== VIEW - EDITOR ============================================================

// ==== part 1 -- pulldown menu with "addreminder-dialog.xul" ============

/**
 *  Builds the 'View' pull-down menu in RL Dialog for all views stored to 
 *  the .prefs
 * 
 *    @param thisLabel  pass in if events or todos/userLists
 */
rmFx_View.MenuBuild = function (thisLabel) {
   rmFx_View.prefViewsLoad ();

   var exportView = "";   
   var mode = (isReminderTabSelected() == true)  ? "Event" : "Todo";
   
   // check if "filterViewLast" + mode is a valid 'View' (could have been removed
   //   with View Editor)
   var lastLabel = document.getElementById("filterViewLast" + mode).label;  
   document.getElementById("filterViewLast" + mode).setAttribute('hidden', true);

   // delete all 'View' items
   var mList = document.getElementById(thisLabel);
   var count = mList.childNodes.length;
   while ( count-- ) {
         mList.removeChild(mList.childNodes[count]);
   }

   var j =0;
   while (gRmFx_Views.Label[j] != null) {
      if (gRmFx_Views.Label[j].length > 0) {
         
         // check if "filterViewLast" + mode is a valid 'View' (could have been removed
         //   with View Editor)
         if (gRmFx_Views.Label[j] == lastLabel) {
            document.getElementById("filterViewLast" + mode).removeAttribute('hidden');
         }            
         
         var m1 = document.createElement("menuitem");
            m1.setAttribute("type" , "checkbox");
            m1.setAttribute("autocheck" , "false");
            m1.setAttribute("oncommand", "rmFx_View.Set(this);");
         
            m1.setAttribute("label", gRmFx_Views.Label[j]);
            m1.setAttribute("value", gRmFx_Views.Items[j]);
         
            // tooltiptext  displays the 'value' of this 'View'
            // need to change from 'general' to 'local' Criteria
            m1.setAttribute("tooltiptext", rmFx_View.CriteriaExchange(gRmFx_Views.Items[j]));

            if (gRmFx_Views.Label[j].toLowerCase() == gRmFx_Views.cLabel[mode].toLowerCase()) {
                  m1.setAttribute("checked",true);
                  exportView = gRmFx_Views.Label[j];
            }
         rmFxUtil.dump2Console ('viewPrefs', "rmFx_View.MenuBuild ::" 
               + "   menu item:" + j + " item:" + gRmFx_Views.Label[j]); 
         mList.appendChild(m1); // after node 1 (menuseparator) 
      }     
      j++;
   }
   var m1 = document.createElement("menuseparator");
   mList.appendChild(m1);
   
   // add the 'View Editor'
   var m1 = document.createElement("menuitem");
   m1.setAttribute("oncommand", "rmFx_View.Manage(this);");
   m1.setAttribute("label", stttEditor);
   m1.setAttribute("value", "");
   m1.setAttribute("tooltiptext", stttEdit);
      mList.appendChild(m1);
      
   // if View selected, add the Export/Send menu item
   if (exportView != "") {
      var m1 = document.createElement("menuseparator");
      (mList.appendChild(m1));

      var m1 = document.createElement("menuitem");
      m1.setAttribute("oncommand", "rmFx_View.ExportView(this);");
      m1.setAttribute("label", sViewsExportSend + " [" + exportView + "]");
      m1.setAttribute("value", "");
      m1.setAttribute("tooltiptext", sViewsExportSend);
         mList.appendChild(m1);
   }
   
   //rmFxUtil.dump2Console('error', "menubuild2");
}


// ==== part 2 -- select a 'View'  =============

/**
 *  With 'View' popup menu selection the RL Dialog Title is set 
 *  and the RL list is re-fill matching the 'View' criteria
 */
rmFx_View.Set = function (thisLabel) {
// thisLabel.parentNode.id  $[0] = [string] "filterViewStack"
// thisLabel.parentNode.id  $[1] = [string] "filterViewStackTodo"

   var mode = (thisLabel.parentNode.id == "filterViewStack") ? "Event" : "Todo";
   var dmode = (thisLabel.parentNode.id == "filterViewStack") ? "" : "Todo";
   
   if (thisLabel.hasAttribute('checked') == true) {
      thisLabel.removeAttribute("checked");

      gRmFx_Views.cLabel[mode] = "";
      gRmFx_Views.cItems[mode] = "";
      document.getElementById("displayType" + dmode).selectedIndex = 0;
      document.getElementById("displayType" + dmode).setAttribute("tooltiptext", "");
      
      document.getElementById("filterViewLast" + mode).setAttribute("tooltiptext", "");
   
   } else {
      thisLabel.setAttribute("checked", "true");
      
      gRmFx_Views.cLabel[mode] = thisLabel.label;
      gRmFx_Views.cItems[mode] = thisLabel.value;

      var ttt = rmFx_View.CriteriaExchange(gRmFx_Views.cItems[mode]);
 
      document.getElementById("displayType" + dmode).selectedIndex = 8;
      document.getElementById("displayType" + dmode).setAttribute("tooltiptext", ttt);

      document.getElementById("filterViewLast" + mode).setAttribute("label", gRmFx_Views.cLabel[mode]);
      document.getElementById("filterViewLast" + mode).setAttribute("value", gRmFx_Views.cItems[mode]);
      document.getElementById("filterViewLast" + mode).setAttribute("tooltiptext", ttt);

      document.getElementById("filterViewLast" + mode).removeAttribute('hidden');

      var currentViews = gRmFx_Views.cPrefs.split(";");
      if (mode == "Event") gRmFx_Views.cPrefs = thisLabel.label + ";" + currentViews[1];
      if (mode == "Todo")  gRmFx_Views.cPrefs = currentViews[0] + ";" + thisLabel.label;
      reminderFox_setUnicodePref("viewcurrent", gRmFx_Views.cPrefs); 
   }
   refillLists();        // calls rmFx_View.SetTitel();
}

/**
 *  Set/Reset the "RL Dialog" Title with the 'currentview' name
 *  and sets gRmFx_Views.cDateSpan
 */
rmFx_View.SetTitel = function (isRemindersOrTodosString) {
   var reminderTab = isRemindersOrTodosString == "reminders" || (isRemindersOrTodosString != "todos" && isReminderTabSelected()); 
	
   var mode = (reminderTab == true)  ? "Event" : "Todo";
   var dmode = (reminderTab == true)  ? "" : "Todo";
   
   if (document.getElementById("displayType" + dmode).selectedIndex  < 8) {
      document.title = sRmFxTitel; 
      gRmFx_Views.cLabel[mode] = "";
      gRmFx_Views.cItems[mode] = "";
      document.getElementById("displayType" + dmode).setAttribute("tooltiptext", "");
      
   } else {   
      document.title = sRmFxTitel + "    " + sViewsName 
            + ": [" + document.getElementById("filterViewLast" + mode).getAttribute("label") + "]";
      gRmFx_Views.cLabel[mode] = document.getElementById("filterViewLast" + mode).getAttribute("label");
      gRmFx_Views.cItems[mode] = document.getElementById("filterViewLast" + mode).getAttribute("value");
      var ttt = rmFx_View.CriteriaExchange(gRmFx_Views.cItems[mode]);
       
      document.getElementById("filterViewLast" + mode).setAttribute("tooltiptext", ttt);
      document.getElementById("displayType" + dmode).setAttribute("tooltiptext", ttt); 
   }
   
   gRmFx_Views.cDateSpan = { start: null, end: null };  
   if (gRmFx_Views.cLabel[mode] != "") {
      if (gRmFx_Views.cItems[mode].search(/DATE:/) != -1) {
         var dateString = gRmFx_Views.cItems[mode].split("DATE:")[1].split(";")[0];
         rmFx_View.vDateSpan(dateString);
      }  
   }
}


rmFx_View.FilterView = function(event) {
     var mode = (isReminderTabSelected() == true)  ? "Event" : "Todo";

     var cLabel = event.currentTarget.label;
     gRmFx_Views.cLabel[mode] = cLabel;
     gRmFx_Views.cItems[mode] = event.currentTarget.value;
     document.title = sRmFxTitel + "    " + sViewsName  + "  [" + gRmFx_Views.cLabel[mode] + "]";
     refillLists();
}


// === part 3 -- Manage the 'View's  =============
/**
 *   call 'rmFx_View.ManageLoad()' to load the defined 'View's from the pref 
 */      rmFx_View.Manage = function () {
   window.openDialog("chrome://reminderfox/content/categories/rmFxViewEditor.xul",
         "rmFx_View.ManageDialog", "chrome,resizable,modal" );
}

/**
 *  build the <menupopup id='criteria_Labels'> from .prefs entiry;
 *  'value'  is used to work on internal string as stored with the .views prefs
 */
rmFx_View.ManageLoad = function (sortMode) {
      var view_List = document.getElementById('view_List');
      var criteria_List = document.getElementById('criteria_List');
      var criteria_Labels = document.getElementById('criteria_Labels');
      
      /* delete all lists and menu   */
      rmFx_View.clearThis(view_List);
      rmFx_View.clearThis(criteria_List);
      rmFx_View.clearThis(criteria_Labels);

      // add menuitems from .prop to ensure we use the same with XUL and js 
      rmFx_View.MenuItems (criteria_Labels, sViewLocalDesc);  //  "SUMMARY");
      rmFx_View.MenuItems (criteria_Labels, sViewLocalCat);   //  "CATEGORIES");
      rmFx_View.MenuItems (criteria_Labels, sViewLocalNotes); //  "NOTES");
      rmFx_View.MenuItems (criteria_Labels, sViewLocalLoc);   //  "LOCATION");
      rmFx_View.MenuItems (criteria_Labels, sViewLocalDate);  //  "DATE");

    
   // ("--- load the 'View's from .prefs to 'view_List' ---"); 
   try { // gW UnicodePref
      gRmFx_Views.Pref = reminderFox_getUnicodePref(REMINDER_FOX_PREF + "." + "views"); 
      var aViewsPref = gRmFx_Views.Pref.split(";>,")
      
      var view_List = document.getElementById('view_List');

      var vCount = aViewsPref.length;
      while ( vCount -- ) {
         var m1 = document.createElement("listitem");
         // apply parameters & insert before node 0
         if (aViewsPref[vCount] != "") {
            
            var xx =aViewsPref[vCount].split("=<");   // ex: FoxInfo=<DATE:TODAY;>,
            m1.setAttribute("label", xx[0]);      // FoxInfo
            m1.setAttribute("value", xx[1]);      // DATE:TODAY

            m1.setAttribute("oncommand", "rmFx_View.ViewFocus(this);");
            m1.setAttribute("tooltiptext", 
              rmFx_View.CriteriaExchange(xx[1])); 

            if ( view_List.childNodes.length == 0 ) {
                view_List.insertBefore(m1,null);
            }
            else {
               view_List.insertBefore(m1,view_List.childNodes[0]);
            }
         }
      }
   } catch (s) {};
   rmFx_ViewEdit.Start(true /*vmRemove*/);
}


/**
 *  Select a 'View' on the 'view_List' and write it's
 *  'criteria's to the 'criteria_List' 
 */
rmFx_View.ViewFocus = function (mode) {
   
   // for the sorting icon set focus and ttt
   if (mode == 'view') {
      document.getElementById('sorter_Box').setAttribute("type", mode); 
      document.getElementById('view_SorterUp').tooltipText = sViewSortUp;
      document.getElementById('view_SorterDown').tooltipText = sViewSortDn;
   } 
   if (mode == 'criteria') {
      document.getElementById('sorter_Box').setAttribute("type", mode);
      document.getElementById('view_SorterUp').tooltipText = sCriteriaSortUp;
      document.getElementById('view_SorterDown').tooltipText = sCriteriaSortDn;
   }

   // get the 'criteria' for selected 'view'
   var view_List= document.getElementById('view_List')
 
   var vLabel = view_List.selectedItem.label;      // FoxInfo
   var vValue = view_List.selectedItem.value;      // DATE:TODAY

   var aValues = vValue.split(";")


   // remove currently displayed 'criteria' and rebuild with new
   var criteria_List = document.getElementById('criteria_List');
   
   rmFx_View.clearThis(criteria_List);
   for (var i = 0; i < aValues.length; i++){
      var m1 = document.createElement("listitem");
         m1.setAttribute("label", rmFx_View.CriteriaExchange(aValues[i]));
         m1.setAttribute("tooltiptext", stttCriteria);
      criteria_List.appendChild(m1);
   }

   rmFx_ViewEdit.Start(false /*vmRemove*/);
}

/**
 *   Add a new 'View' using the 'view_Add' button
 */
rmFx_View.ViewAdd = function (mode) {
   var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
                  .getService(Components.interfaces.nsIPromptService);

   var check = {value: false};      // default the checkbox to false
   var input = {value: sViewsNew};    // default the edit field to 'new'
   if (prompts.prompt(null, sViewsNewTitel, sViewsNewInstruct, input, null, check) == false) {return;};
   
   // OK pressed, input.value holds the value
   aViewEditor2Save = true;  // set to save any changes with close
   
   var view_List = document.getElementById('view_List');
   
   // add this new 'View' ... don't allow '=', ':', ',', ';', '>', '<' in name of viewList
   if (!rmFx_View.vNameValid(input.value, view_List)) return; // noDups

   var m1 = document.createElement("listitem");
      m1.setAttribute("label", input.value);
      m1.setAttribute("value", "SUMMARY:??");
      m1.setAttribute("tooltiptext", "SUMMARY:??");
   view_List.appendChild(m1);
//gW #250123
      view_List.ensureElementIsVisible(m1);
      view_List.addItemToSelection(m1);
   
   view_List.selectedIndex = view_List.childNodes.length -1;
   
   // add to Criteria_List
   var criteria_List = document.getElementById('criteria_List');
   rmFx_View.clearThis(criteria_List);
   
   var m1 = document.createElement("listitem");
      m1.setAttribute("label", (sViewLocalDesc + ":??"));
      m1.setAttribute("tooltiptext", stttCriteria);
   criteria_List.appendChild(m1);
   
//gW #250123
      criteria_List.ensureElementIsVisible(m1);
      criteria_List.addItemToSelection(m1);

   rmFxUtil.dump2Console ('viewModes', "view_List.selectedIndex:"
         + (view_List.childNodes.length -1)); 
      
   sizeToContent();
}


/**
 * Remove a 'View' from 'view_List' using 'view_Remove' button
 */
rmFx_View.ViewRemove = function (mode) {

   var view_List = document.getElementById('view_List');
   var i = view_List.selectedIndex
   if (i == -1) {return};
   
   var viewLabel = view_List.childNodes[i].label

   // prompt the user before Deleting
   var title = reminderFox_getBundle().getString("rf.views.ttt.viewremoveTitel");
   var msg = reminderFox_getBundle().getString("rf.views.ttt.viewremove1")
               + " \"" + viewLabel + "\" " 
               + reminderFox_getBundle().getString("rf.views.ttt.viewremove2");
   var key0 = reminderFox_getBundle().getString("rf.button.ok");
   var key1 = reminderFox_getBundle().getString("rf.button.cancel");
   
   if (rmFxUtil.ConfirmEx(title, msg, key0, key1) == 1 ) {  // cancel pressed
         return;
   }         
   // buttonPressed  OK ... delete

   aViewEditor2Save = true;
   
   var criteria_List = document.getElementById('criteria_List');
   rmFx_View.clearThis(criteria_List);

   view_List.removeChild(view_List.childNodes[i])
   
   // delete 'viewLabel' from "currentview" (Event & Todo !!) 
   //    and if selected as 'filterViewLast' '..Todo'
   //    hide it and select the first menu item
      try {
         gRmFx_Views.cPrefs = reminderFox_getUnicodePref(REMINDER_FOX_PREF + "." + "viewcurrent");
      } catch (ex) {}
      
      var currentViews = gRmFx_Views.cPrefs.split(";");
      if (currentViews[0] == viewLabel) currentViews[0] = "";
      if (currentViews[1] == viewLabel) currentViews[1] = "";
      gRmFx_Views.cPrefs = currentViews[0] + ";" + currentViews[1];
      reminderFox_setUnicodePref("viewcurrent", gRmFx_Views.cPrefs);    
  
   rmFx_ViewEdit.Start(true /*vmRemove*/);
}


// === part 4 -- manage Criteria ====================
/**
 * Select 'criteria' in 'criteria_List' to store it to 'criteria_Vbox'
 */ 
rmFx_View.CriteriaToEdit = function (mode) {

   if (mode.selectedIndex == -1 ) {return};
   
   // set edit 'criteria'
   document.getElementById('sorter_Box').setAttribute("type", "criteria");
      
   document.getElementById('view_SorterUp').tooltipText =   sCriteriaSortUp;
   document.getElementById('view_SorterDown').tooltipText = sCriteriaSortDn;
   
   var criteriaString = mode.selectedItem.label;
   var thisCritera = criteriaString.split(":")[0];
   var thisValue = criteriaString.split(":")[1];
   
   // select the menu item from pulldownmenu 'criteria_Typs'
   var criteria_Typs = document.getElementById('criteria_Typs');
   for (var i=0; i < criteria_Typs.childNodes[0].childNodes.length; i++ ) { 
      if (thisCritera.toLowerCase() == criteria_Typs.childNodes[0].childNodes[i].label.toLowerCase()) {
            criteria_Typs.selectedIndex = i;
      }
   }
   rmFx_ViewEdit.CriteriaEdit(thisCritera /*cType*/, thisValue /*cValue*/);
}


/**
 * Read the 'criteria_Vbox' string(s) and replace/add to 'criteria_List'
 * 
 */
rmFx_View.CriteriaEditEnter = function () {

   var view_List = document.getElementById('view_List').selectedIndex;

   var criteria_Typs  = document.getElementById('criteria_Typs').label
   var generalTyp = rmFx_View.Criteria2General(criteria_Typs).toUpperCase();

   rmFxUtil.dump2Console ('viewCriteria', "CriteriaEditEnter  criteria_Typs::" 
            + criteria_Typs + "   generalTyp:" + generalTyp); 
    
   switch (generalTyp) {
   case "DATE": {
      aViewEditorChanged = true;

      // 'DATE' needs different code here for 'Panel'                          //gWViewDATE
      if (rmFx_View.vHasPanel()) { //   with 'panel'  supported
           
         var newString = "";
         var eStringBegin = document.getElementById('dateBoxBegin').value 
         var eStringEnd   = document.getElementById('dateBoxEnd').value;
      
       /* 'old'/deprecated strings not allow for second/end value
        *   need the 'locale' strings,  check/convert  strings to 'general'     
        */
         eStringBegin = rmFx_View.Criteria2General(eStringBegin);
         eStringEnd   = rmFx_View.Criteria2General(eStringEnd);
          
         if (eStringBegin.search(/NEXT_WEEK|NEXT_2WEEKS/) > -1)  eStringEnd = "";
   
         // check second string, if empty or 0 (null)
         if ((eStringEnd == "") 
            || (parseInt(eStringEnd.substring(0,eStringEnd.length-1)) == 0))  {
         newString = eStringBegin;
            eStringBegin = "";
            eStringEnd = "";
         } else {
            // if 'eStringBegin' has a zero value, set eStringBegin == eStringEnd and erase eStringBegin
            if (parseInt(eStringBegin.substring(0,eStringBegin.length-1)) == 0) {
               newString = eStringEnd;
               eStringBegin = "";
               eStringEnd = "";
            }
            // begin & end (gRmFx_Views.cDateSpan)  .. so sort it
            if (eStringEnd != "") { 
               if (rmFx_View.vDateSpanFromString(eStringBegin) > rmFx_View.vDateSpanFromString(eStringEnd)) {
                  var temp = eStringBegin;
                  var eStringBegin = eStringEnd;
                  eStringEnd = temp;
               }
               newString = eStringBegin + "," + eStringEnd;
            }
         }
         switch (newString) {
               case '0D':  { newString = 'TODAY'; break;}
               case '0W':  { newString = 'CURRENT_WEEK'; break;}
               case '0M':  { newString = 'CURRENT_MONTH'; break;}
               case '0Y':  { newString = 'CURRENT_YEAR'; break;}
         }       
                   
      } else { // no 'panel'  .. TB2/FX2 code !!  DATE with pulldown for items
         var dateString = document.getElementById('criteria_DateMenu').label;
         var newString =rmFx_View.Criteria2General(dateString);
      }
      
      var newCriteria = generalTyp + ":" + newString;    // "Datum:-1M,10D" 
      rmFxUtil.dump2Console ('viewCriteria', "CriteriaEditEnter  DATE::" + newCriteria); 
      break;
   }  // case "DATE":
   
   default:  { // string op  
      if (generalTyp == 'CATEGORIES') {
         var newString = document.getElementById('inputRmCategories').value;
      } else {
            var newString = document.getElementById('criteria_Box').value;
      }
      if (newString != "" ) {    // check for valid characters 
         if (!rmFx_View.vNameValid(newString)) return; // noDups

         aViewEditorChanged = true; 
         var newCriteria  = generalTyp + ":" + newString;  // "Notiz:xxyyxx"
      }
      rmFxUtil.dump2Console ('viewCriteria', "CriteriaEditEnter  generalSTRING::" + newCriteria); 

   } // default string op  
   } // switch generalTyp

   if (!aViewEditorChanged) { rmFx_ViewEdit.CriteriaEnter("-"); return;}
   
   
   // the 'criteria' changed, so store it to current 'view_List' item 
   // and reload 'criteria_List' to get 'locale' values
   
   var criteria_List = document.getElementById('criteria_List');
   var sCriteria_List = criteria_List.selectedIndex;

   var m1 = document.createElement("listitem");
      m1.setAttribute("label", newCriteria);     // 'local'
      m1.setAttribute("tooltiptext", stttCriteria);   //   "Select a 'Criteria' to edit"

   if (sCriteria_List == -1) { // this is a ADD because no item was selected in 'criteria_List'
      criteria_List.appendChild(m1);

//gW #250123
      criteria_List.ensureElementIsVisible(m1);
      criteria_List.addItemToSelection(m1);
      
      var xCount = criteria_List.childNodes.length
      if ((xCount == 2) && (criteria_List.childNodes[0].label == "")) {
         criteria_List.removeItemAt(0);
         criteria_List.selectedIndex = 0;
      }
   } else {       // replace the current item
      var oldNode = criteria_List.childNodes[sCriteria_List];
      criteria_List.replaceChild(m1, oldNode);
//gW #250123
      criteria_List.ensureElementIsVisible(m1);
      criteria_List.addItemToSelection(m1);
   }

   // now change the 'value' of the 'View' 
   for (var i=0; i < criteria_List.childNodes.length; i++) {
      if (i==0) {
         var criteria_ListString = criteria_List.childNodes[0].label;
      } else {
         criteria_ListString += ";" + criteria_List.childNodes[i].label;
      }
   }
   document.getElementById('view_List').childNodes[view_List].value = criteria_ListString;
   document.getElementById('view_List').childNodes[view_List].tooltipText = criteria_ListString;
   
   rmFxUtil.dump2Console ('viewCriteria', "CriteriaEditEnter  aViewEditorChanged::" + criteria_ListString); 
   
   aViewEditorChanged = false;
   aViewEditor2Save = true;
   rmFx_View.ViewFocus ('criteria');
}

/**
 *   ADD a new 'criteria' to the 'criteria_List' for the selected 'View'
 */
rmFx_View.CriteriaAdd = function (mode) {
    document.getElementById("criteria_List").clearSelection();
    
   rmFx_ViewEdit.CriteriaAdd(mode);
}

/**
 *   REMOVE a 'criteria' in 'criteria_List' for the selected 'View'
 */
rmFx_View.CriteriaRemove = function (mode) {
   var aa= document.getElementById('criteria_List')
   try {
      aa.removeChild(aa.childNodes[aa.selectedIndex])
      document.getElementById('criteria_Box').value = "";
      
   // now change the 'value'
      var criteria_ListString ="";
      for (var i=0; i < aa.childNodes.length; i++) {
         if (i==0) {
            var criteria_ListString =aa.childNodes[0].label;
         } else {
            criteria_ListString += ";" + aa.childNodes[i].label;
         }
      }
      i = document.getElementById('view_List').selectedIndex
      document.getElementById('view_List').childNodes[i].value = criteria_ListString
   
      aViewEditorChanged = true;
   } catch (e) {}
   rmFx_ViewEdit.CriteriaEnter(mode);
}

/**
 *    With 'criteria_Typs' changed, check for double 'DATE'
 *    and change to 'ADD' mode
 */
rmFx_View.CriteriaTypChanged = function (event){
   
   document.getElementById("criteria_List").clearSelection();

   var locType = event.target.label;
   var generalTyp = rmFx_View.Criteria2General(locType);
    
   if (generalTyp == 'DATE' )  {                                           //gWViewDATE
        // more than one 'DATE' item per 'view' doesn't makes sense
      var criteria_List = document.getElementById('criteria_List');
      for (var i=0; i < criteria_List.childNodes.length; i++) {
         if (criteria_List.childNodes[i].label.search(sViewLocalDate + ":") == 0) {
            document.getElementById('criteria_Typs').selectedIndex = 0;
            rmFxCore.statusSet (sViewDateAlreadydefined);
            return;
         }
      }   
   }
   rmFx_ViewEdit.CriteriaAdd (generalTyp, "" /*cString*/);
}

// ---- 'DATE' panel functions    ------------------   //gWViewDATE
/**
 *  
 * Open 'panel' to let the user change the 'Date' values
 *      for 'viewvalueX' = {num}{D|W|M|Y}
 *      and optional the old values like 'TODAY'
 *
 *   @param  anchor:    object for pointing the panel to begin/end
 *   with anchor.value: a 'old' string or  'new' values ({num}{D|M|Y})
 *   @param  spanText:  holds the title text for the opened panel  
 */
rmFx_View.CriteriaDatePanel = function (anchor, spanText) {
     
   var dateString = anchor.value;  
   if ((dateString == "") || (dateString == "")) dateString ="0D";  // set 'today'

   var periode = dateString.substr(-1);
   if (periode.search(/D|W|M|Y/) == -1) return 0; 
  
   var iValue = parseInt(dateString.substring(0,dateString.length-1));
   var I = 0;
   switch (periode) {
        case 'D': I = 0; break;
        case 'W': I = 1; break;
        case 'M': I = 2; break;
        case 'Y': I = 3; break;
   }
   document.getElementById("spanPeriod").selectedIndex = I; 
   document.getElementById("dateGroup").selectedIndex = (iValue < 0) ? 0 : 1; 
   document.getElementById("dateValue").value = Math.abs(iValue);
    
   // 'anchor.id' holds a string for "begin/end" indication and set for an
   // attribute 'timeType' to have it with closing the panel
   document.getElementById("criteria_DateEdit_Titel").attributes["timeType"].value=anchor.id; 
   document.getElementById("criteria_DateEdit_Titel").value = spanText;
  
   // use 'panel' for DATE entry/edit                                   //gWViewDATE
      var panel = document.getElementById("criteria_DateEdit");   
      panel.removeAttribute('hidden');
      panel.openPopup(anchor, 'after_start', -1, -1); 
}

/**
 *   Read the panel 'criteria_DateEdit' settings and write back to the
 *   "timeType" textbox ('dateBoxBegin' or 'dateBoxEnd') 
 */
rmFx_View.CriteriaDatePanelClose = function (xEvent) {
    
    // 'timeType'  is one of the two textboxes for DATE
    var timeType = document.getElementById("criteria_DateEdit_Titel").attributes["timeType"].value;
    
    var dValue = parseInt (document.getElementById("dateValue").value);
    var future = parseInt (document.getElementById("dateGroup").selectedIndex);
    var periode = document.getElementById("spanPeriod").selectedIndex;
    
    //    add 'W' for week 
    var spanString = ((future == 0) ? "-" : "") 
          + dValue 
          + ((periode == 0) ? "D" : 
            ((periode == 1) ? "W" : 
            ((periode == 2) ? "M" : "Y")));

    rmFxUtil.dump2Console ('CriteriaDatePanelClose', "rmFx_View.CriteriaDatePanelClose" 
            + " future:" + future
            + " dValue:" + dValue
            + " period:" + periode
            + "\n spanString:" + spanString + "  timeType" + timeType
            + "\n" + rmFxUtil.localeDate(rmFx_View.vDateSpanFromString(spanString)));

    document.getElementById(timeType).value = spanString;
    document.getElementById(timeType).tooltipText 
        = rmFxUtil.localeDate(rmFx_View.vDateSpanFromString(spanString));
}


// ===  Support functions   ====================================================


   rmFx_View.vHasPanel = function () {
      var panel = document.getElementById("criteria_DateEdit");
      return (panel.accessibleType != null)
   }

   rmFx_View.vNameValid = function (thisName, knowNames) {
      if (thisName.search(/(=|:|;|>|<)/g) != -1) {
         rmFxCore.statusSet (sValidNameString);
         return false;  // not allowed
      }
      // if 'knownNames' check
      if (knowNames) {
         for (var i=0; i < knowNames.children.length; i++) {
            if (thisName == knowNames.children[i].label) {
               rmFxCore.statusSet (sValidNameString);
               return false;
            }
         }     
      }
      return true;
   }



/**
 *   The pref REMINDER_FOX_PREF + "." + "views" holds the viewsLabel aunf viewsItems
 * 
 *   See also the globals gRmFx_Views.Label, gRmFx_Views.Items, gRmFx_Views.cDateSpan, gRmFx_Views.Pref
 */
rmFx_View.prefViewsLoad = function () {
   var aNewItem; 

   try {
      gRmFx_Views.Pref = reminderFox_getUnicodePref(REMINDER_FOX_PREF + "." + "views"); 
   } catch (ex) {
      gRmFx_Views.Pref = "";
      gRmFx_Views.Label = {};
      gRmFx_Views.Items = {};
   }   
   
   if ((gRmFx_Views.Pref != null) && (gRmFx_Views.Pref != "")) {
      gRmFx_Views.Label = {};
      gRmFx_Views.Items = {};      
      var aViewsPref = gRmFx_Views.Pref.split(";>,");
      var vCount = aViewsPref.length; 
      var j = 0;
      for (var i = 0; i < vCount; i++) {
         if ((aViewsPref[i] != "") && (aViewsPref[i] != null)) {
            aNewItem = aViewsPref[i].split("=<");  
            gRmFx_Views.Label[j] = aNewItem[0];     
            gRmFx_Views.Items[j] = aNewItem[1];
            j++;      
         }
      }
   }
}

rmFx_View.prefViewCurrentLoad = function () {

   rmFx_View.prefViewsLoad();
   if (gRmFx_Views.cPrefs == "") {
   
      // check for 'current View' if available set/unhide the menu 'filterViewLast'
      try {
         gRmFx_Views.cPrefs = reminderFox_getUnicodePref(REMINDER_FOX_PREF + "." + "viewcurrent");
      } catch (ex) {}
      
      if (gRmFx_Views.cPrefs != "") {
         var aViewCurrent = gRmFx_Views.cPrefs.split(";");
   
         for (var i = 0; i < 2; i++) {
            var mode = (i == 0) ? "Event" : "Todo";
   
            if (aViewCurrent[i] != "") {  // currentView Label .. go and check in gRmFx_Views.Label
               var j = 0;
               while ((gRmFx_Views.Label[j] != null) && (gRmFx_Views.Label[j] != aViewCurrent[i])){
                  j++;
               }
               if (gRmFx_Views.Label[j] != null){
                  gRmFx_Views.cLabel[mode] = gRmFx_Views.Label[j];
                  gRmFx_Views.cItems[mode] = gRmFx_Views.Items[j];
                  var ttt = rmFx_View.CriteriaExchange(gRmFx_Views.cItems[mode]);
               
                  document.getElementById("filterViewLast" + mode).setAttribute("label", gRmFx_Views.cLabel[mode]);
                  document.getElementById("filterViewLast" + mode).setAttribute("value", gRmFx_Views.cItems[mode]);       
                  document.getElementById("filterViewLast" + mode).setAttribute("tooltiptext", ttt); 
         
                  document.getElementById("filterViewLast" + mode).removeAttribute('hidden');   
               } 
            }
         }  // for i 
      }     // if (aViewCurrent  
   }
      rmFxUtil.dump2Console ('viewPrefs', "rmFx_View.prefViewCurrentLoad :"
         + "\nviews pref:" + gRmFx_Views.Pref 
         + "\nviewcurrent pref:" + gRmFx_Views.cPrefs); 
}

/**
 *   'gViewsPref' build with Views/Criteria 
 *   also build 'gRmFx_Views.Label' and 'gRmFx_Views.Items'
 */
rmFx_View.prefBuildStr = function () {
    var view_List = document.getElementById('view_List');

    gRmFx_Views.Pref   = ""; 
    gRmFx_Views.Label  = {};  
    gRmFx_Views.Items  = {};  

    for (var i=0; i< view_List.childNodes.length; i++) {
        gRmFx_Views.Label[i] = view_List.childNodes[i].label;  
            
        var iValues = view_List.childNodes[i].value.split(";");
        for (var j = 0; j < iValues.length; j++) {
            var thisLabel = rmFx_View.Criteria2General(iValues[j].split(":")[0]);
            var thisValues = iValues[j].split(":")[1];
            iValues[j] = thisLabel + ":" + thisValues;
        }
        gRmFx_Views.Items[i] = iValues.join(";");
        gRmFx_Views.Pref += gRmFx_Views.Label[i] + "=<" + gRmFx_Views.Items[i] + ";>,";
    } 
    rmFxUtil.dump2Console ('viewPrefs', "rmFx_View.prefBuildStr  build:" + gRmFx_Views.Pref);
    return gRmFx_Views.Pref;
}


/**
 *      Convert 'gRmFx_Views.cDateSpan' to global start/end date values 
 */
rmFx_View.vDateSpan = function (dateSpan) {                                   //gWViewDATE

    gRmFx_Views.cDateSpan = { start: null, end: null };  

    var dateSpanDetail = dateSpan.split(",");
    if (dateSpanDetail.length < 1 ) return;  // no 'dateSpan', clear start/end dates
    
    // --- searchFor : see 'addReminderDialog.js  at function getStartAndEndDates
    var dateType = -1;
    switch (dateSpanDetail[0].toUpperCase()) {
        case 'TODAY':
        case '0D':             {dateType = 3;  break;}
        case 'CURRENT_WEEK':
        case '0W':             {dateType = 2;  break;}
        case 'CURRENT_MONTH':
        case '0M':             {dateType = 1;  break;}
        case 'CURRENT_YEAR':
        case '0Y':             {dateType = 0;  break;}

        case 'NEXT_WEEK':      {dateType = 4; break;}
        case 'NEXT_2WEEKS':    {dateType = 5; break;}
    } 
    
    if (dateType > -1) {  // 'DATE'  has 'old' strings 
        // .. use 'addReminderDialog' function  to get the dates 
        var theseDates = getStartAndEndDates(dateType, true);
    }  
       else {           //  'DATE'  has 'new' value(s)
        var theseDates = { start: null, end: null };
                 
        theseDates.start = rmFx_View.vDateSpanFromString(dateSpanDetail[0]);
        if (dateSpanDetail.length > 1) { 
            theseDates.end   = rmFx_View.vDateSpanFromString(dateSpanDetail[1]);
        } else {    
            theseDates.end = new Date();  //  'dateSpan2' obmitted  --> set 'today' 
        }
        // check for .start > .end --> exchange values !!
        if (theseDates.end < theseDates.start) {
            var temp = theseDates.start;
            theseDates.start = theseDates.end;
            theseDates.end = temp;
        }
    }
    gRmFx_Views.cDateSpan.start = theseDates.start;
    gRmFx_Views.cDateSpan.end = theseDates.end;
}

/**
 *   Convert 'dateString' string to Date() value relative to 'today'
 */
rmFx_View.vDateSpanFromString = function (dateString) {
    var periode = dateString.substr(-1);
    if (periode.search(/D|W|M|Y/) == -1) return 0; 
    dateString = dateString.substring(0,dateString.length-1);
    
    var numValue = parseInt(dateString);
    
        var dD = 0;
        var dM = 0;
        var dY = 0;
        switch (periode) {
            case 'D': dD = numValue; break;
            case 'M': dM = numValue; break;
            case 'Y': dY = numValue; break;
            case 'W': dD = numValue*7; break;
        }
    var sday = new Date();
    return new Date( sday.getYear()+ 1900 + dY, 
                     sday.getMonth() + dM, sday.getDate() +dD);
}

/**
 *    exchange  'local' and 'general' criteria descriptors 
 */
rmFx_View.CriteriaExchange = function (criteria) {        
        var xCriteria = criteria.split(";");
        for (var j=0; j < xCriteria.length; j++) {
            
            var labelString = xCriteria[j].split(":")[0];
            var valString   = xCriteria[j].split(":")[1];

            if (xCriteria[j].split(":")[0] == "DATE") {
                
                // for 'DATE' change {num}{D|M|Y} values to strings if possible    
                if (valString.search(/,/) == -1) {  // only one value
                    if (valString == '0D')  valString = rmFx_View.Criteria2Locale('TODAY');
                    if (valString == '0W')  valString = rmFx_View.Criteria2Locale('CURRENT_WEEK');
                    if (valString == '0M')  valString = rmFx_View.Criteria2Locale('CURRENT_MONTH');
                    if (valString == '0Y')  valString = rmFx_View.Criteria2Locale('CURRENT_YEAR');
                }
                valString = rmFx_View.Criteria2Locale(valString); 
            } 

            xCriteria[j] = rmFx_View.Criteria2Locale(labelString) 
                    + ":" + valString;
        } 
        return xCriteria.join(";");
}

        rmFx_View.Criteria2Locale = function (criteria) {
            switch (criteria) {
                case "SUMMARY":             {return  sViewLocalDesc; }
                case "CATEGORIES":          {return  sViewLocalCat; }
                case "LOCATION":            {return  sViewLocalLoc; }
                case "NOTES":               {return  sViewLocalNotes; }
                case "DATE":                {return  sViewLocalDate; }
                
                case "TODAY":               {return sViewToday;}         // :0
                case "CURRENT_WEEK":        {return sViewCurWeek;}       // :1
                case "CURRENT_MONTH":       {return sViewCurMonth;}      // :2
                case "CURRENT_YEAR":        {return sViewCurYear;}       // :3

                case "NEXT_WEEK":           {return sViewNextWeek;}      // :4
                case "NEXT_2WEEKS":         {return sViewNext2Weeks;}    // :5
            }       
            return criteria;    // nothing matched, so return original criteria value
        }

        rmFx_View.Criteria2General = function (criteria) {
            switch (criteria) {        
                case sViewLocalDesc:     {return  "SUMMARY"; }
                case sViewLocalCat:      {return  "CATEGORIES"; }
                case sViewLocalLoc:      {return  "LOCATION"; }
                case sViewLocalNotes:    {return  "NOTES"; }
                case sViewLocalDate:     {return  "DATE"; }

                case sViewToday:          {return  "TODAY";}              // :0
                case sViewCurWeek:        {return  "CURRENT_WEEK";}       // :1
                case sViewCurMonth:       {return  "CURRENT_MONTH";}      // :2
                case sViewCurYear:        {return  "CURRENT_YEAR";}       // :3

                case sViewNextWeek:       {return  "NEXT_WEEK"; }
                case sViewNext2Weeks:     {return  "NEXT_2WEEKS" };
            }       
            return criteria;    // nothing matched, so return original criteria value
        }


rmFx_View.vSaveAndClose = function (mode) {

    rmFxUtil.dump2Console ('viewSaveAndClose', "rmFx_View.vSaveAndClose  changed:" + aViewEditorChanged); 

   if (aViewEditor2Save == false) {window.close(); return};

   var title = reminderFox_getBundle().getString("rf.views.closeTitel");   //'View' Editor - Closing";
   var msg   = reminderFox_getBundle().getString("rf.views.closeWarning");
   var key0  = reminderFox_getBundle().getString("rf.views.discard");      //YES, discard";
   var key1  = reminderFox_getBundle().getString("rf.views.noGoBack");     //NO, go back to Editor";
   var key1s  = reminderFox_getBundle().getString("rf.views.noSave");      //NO, save";

   if (mode == 'CANCEL') {  // ("--- rmFx_View.vSaveAndClose w 'CANCEL'---");

      if (rmFxUtil.ConfirmEx(title, msg, key0, key1) == 1 ) {
         return;  // 'No' pressed .. return to XUL
      }
      window.close(); // buttonPressed  'OK' ... discard all changes!!
      return;
   }
   
   if (mode == 'X') {  // ("--- the window 'X' at the header was used .. now handle the edited 'prefs' ---");
      if (rmFxUtil.ConfirmEx(title, msg, key0, key1s) == 0 ) { 
         return;  // buttonPressed  'OK' ... delete
      }
   }
    
   // 'views' prefs string saved    
   gRmFx_Views.Pref = rmFx_View.prefBuildStr();
   reminderFox_setUnicodePref("views", gRmFx_Views.Pref);
   rmFxUtil.dump2Console ('viewPrefs', "rmFx_View.vSaveAndClose  prefs:" + gRmFx_Views.Pref); 
   window.close();
}


rmFx_View.clearThis = function (thisName) {
    var count = thisName.childNodes.length;
    while ( count-- ) {
        thisName.removeChild(thisName.childNodes[count]);
    }       
}


rmFx_View.MenuItems = function (xList, Label) {
            var m1 = document.createElement("menuitem");
            m1.setAttribute("label", Label);
            xList.appendChild(m1);
}




// ==== Button, List/Textboxes control  ========================================
function rmFx_ViewEdit () {
}
   rmFx_ViewEdit.Start = function (vmRemove) {
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      rmFx_ViewEdit.View     (false /*vmAdd*/, vmRemove /*vmRemove*/);
      rmFx_ViewEdit.Criteria (true  /*cmAdd*/, true     /*cmRemove*/);

      rmFx_ViewEdit.cEdit (false /*c_List*/, true /*c_Mode*/, sViewsChange /*cmLabel*/, "-" /*cType*/, "" /*cString*/);
        
      // OKbutton
      document.getElementById('OK').removeAttribute("disabled");
   }
         
   rmFx_ViewEdit.CriteriaEdit = function (cType, cString) {
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      rmFx_ViewEdit.View     (true  /*vmAdd*/, true  /*vmRemove*/);
      rmFx_ViewEdit.Criteria (false /*cmAdd*/, false /*cmRemove*/);
         
      rmFx_ViewEdit.cEdit (false /*c_List*/, false /*c_Mode*/, sViewsEdit /*cmLabel*/, cType, cString);

      // OKbutton
      document.getElementById('OK').setAttribute("disabled", true);
   }
      
   rmFx_ViewEdit.CriteriaAdd = function (cType) {
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      rmFx_ViewEdit.View     (false /*vmAdd*/, false /*vmRemove*/);
      rmFx_ViewEdit.Criteria (false /*cmAdd*/, false /*cmRemove*/);
        
      rmFx_ViewEdit.cEdit (false /*c_List*/, false /*c_Mode*/, sViewsAdd /*cmLabel*/, cType /*cType*/, "" /*cString*/);

      // OKbutton
      document.getElementById('OK').setAttribute("disabled", true);
   }
   
   rmFx_ViewEdit.CriteriaEnter = function (cType) {
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      rmFx_ViewEdit.View     (false /*vmAdd*/, false /*vmRemove*/);
      rmFx_ViewEdit.Criteria (false /*cmAdd*/, true  /*cmRemove*/);

      rmFx_ViewEdit.cEdit (false /*c_List*/, true /*c_Mode*/, sViewsChange /*cmLabel*/, cType, "" /*cString*/);
      
      // OKbutton      
      document.getElementById('OK').removeAttribute("disabled");
      }
      
    
      // ------------------------------------------------------------------     
      /**
        *    Control the 'View' buttons Add and Delete
       */
      rmFx_ViewEdit.View = function (vmAdd, vmRemove) {
      // --------------------------------      
         rmFxUtil.dump2Console('viewsTest', "rmFx_ViewEdit.View   vmAdd:" 
            + vmAdd + " vmRemove:" + vmRemove);

         document.getElementById('view_Add').setAttribute("disabled",        vmAdd);
         document.getElementById('view_Remove').setAttribute("disabled",     vmRemove);
      }
      
      /**
       *    Control the 'Criteria' buttons Add and Delete
       */
      rmFx_ViewEdit.Criteria = function (cmAdd, cmRemove) {
      // --------------------------------
         rmFxUtil.dump2Console('viewsTest', "rmFx_ViewEdit.Criteria   cmAdd:" 
              + cmAdd + " cmRemove:" + cmRemove);
      
         document.getElementById('criteria_Add').setAttribute("disabled",    cmAdd);
         document.getElementById('criteria_Remove').setAttribute("disabled", cmRemove);
      }
        
     /**
      *   Controls the "criteria_Edit"
      */
      rmFx_ViewEdit.cEdit = function (c_List, c_Mode, cmLabel, locType, cString) {
      // --------------------------------      
         rmFxUtil.dump2Console('viewsTest', "rmFx_ViewEdit.cEdit   c_List:" 
               + c_List + " c_Mode:" + c_Mode + " cmLabel:"+ cmLabel + " locType:" + locType + " cString:" + cString
               + "\n-------------------------");
               
         document.getElementById('criteria_List').setAttribute("disabled",   c_List);
                  
         document.getElementById('criteria_Typs').setAttribute("disabled",   c_Mode); 
         document.getElementById('criteria_Mode').setAttribute("disabled",   c_Mode);
            
         document.getElementById('criteria_Mode').label= cmLabel;

         // disable all 'criteria_VBox'es -- will be enabled based on 'cType'
         document.getElementById('criteria_DateMenu').setAttribute('hidden', true); 
         document.getElementById('criteria_Date').setAttribute('hidden',     true);
         document.getElementById('catHbox').setAttribute('hidden',           true);  

         var cType = rmFx_View.Criteria2General(locType);
         switch (cType.toUpperCase()) {
            case 'DATE': {    //  TB3/FX3  and TB2/FX2 code different !!               //gWViewDATE

               if (rmFx_View.vHasPanel()) {
                  // use DATE with PANEL
                  document.getElementById('criteria_Box').setAttribute('hidden', 'true')
                  document.getElementById('criteria_Date').removeAttribute('hidden')

                  var dateDetail = cString.split(",");
                      if (dateDetail.length < 1 ) return true;  // no 'Date'
                  
                  var eDateBegin = dateDetail[0].toUpperCase();
                      var beginString = eDateBegin; 
                      
                      if (eDateBegin == rmFx_View.Criteria2Locale('TODAY').toUpperCase())         { beginString = "0D"; }
                      if (eDateBegin == rmFx_View.Criteria2Locale('CURRENT_WEEK').toUpperCase())  { beginString = "0W"; }
                      if (eDateBegin == rmFx_View.Criteria2Locale('CURRENT_MONTH').toUpperCase()) { beginString = "0M"; }
                      if (eDateBegin == rmFx_View.Criteria2Locale('CURRENT_YEAR').toUpperCase())  { beginString = "0Y"; }
      
                       if (eDateBegin == rmFx_View.Criteria2Locale('NEXT_WEEK').toUpperCase())    { beginString = dateDetail[0]; }
                       if (eDateBegin == rmFx_View.Criteria2Locale('NEXT_2WEEKS').toUpperCase())  { beginString = dateDetail[0]; }
   
   
                      document.getElementById('dateBoxBegin').value = beginString;
                      
                      // tooltiptext:  
                      if (beginString != eDateBegin) {    // for begin (dateDetail[0]) use strings like 'TODAY' 
                         document.getElementById('dateBoxBegin').tooltipText = eDateBegin
                      } else {                            //   or take {num}{D|M|Y} for it
                          document.getElementById('dateBoxBegin').tooltipText 
                              = rmFxUtil.localeDate(rmFx_View.vDateSpanFromString(beginString)); 
                      }
                          
                      // tooltipText:  for end (dateDetail[1]) take {num}{D|M|Y} 
                  if (dateDetail.length > 1) {
                             document.getElementById('dateBoxEnd').tooltipText 
                                = rmFxUtil.localeDate(rmFx_View.vDateSpanFromString(dateDetail[1])); 
                             document.getElementById('dateBoxEnd').value = dateDetail[1]
                  } else {
                        document.getElementById('dateBoxEnd').value = "";
                  }
                  
               } else { // no 'panel'  .. TB2/FX2 code !! 
                  document.getElementById('criteria_Box').setAttribute('hidden', true)
                  document.getElementById('criteria_DateMenu').setAttribute('hidden', false)

                  /* delete all 'criteria_Date' items  */
                  var cList = document.getElementById('criteria_DateItems');
                  var count = cList.childNodes.length;
                  
                  while ( count-- ) {
                     cList.removeChild(cList.childNodes[count]);
                  }
                  // add menuitems from .prop to ensure we use the same with XUL and js 
                  rmFx_View.MenuItems (cList, sViewToday);     //, "TODAY");
                  rmFx_View.MenuItems (cList, sViewCurWeek);   //, "CURRENT_WEEK");
                  rmFx_View.MenuItems (cList, sViewNextWeek);  //, "NEXT_WEEK");
                  rmFx_View.MenuItems (cList, sViewNext2Weeks);//, "NEXT_2WEEKS");
                  rmFx_View.MenuItems (cList, sViewCurMonth);  //, "CURRENT_MONTH");

                  // select 'cValue' from pull down menu 
                  var criteriaDate = document.getElementById('criteria_DateMenu')
                  for (var i=0; i < criteriaDate.childNodes[0].childNodes.length; i++ ) { 
                     if (cString == criteriaDate.childNodes[0].childNodes[i].label) {
                           criteriaDate.selectedIndex = i;
                     }
                  } // select cValue
               } // no 'panel'
               break;
            } // case DATE
            
            case 'CATEGORIES': {    // show the 'categories pull-down menu, delete the label
               document.getElementById('criteria_Box').setAttribute('hidden',   true);
               document.getElementById('catHbox').removeAttribute('hidden'); 
               document.getElementById('catLabel').value = "";
  
               document.getElementById('inputRmCategories').value = cString;
               break; 
            }

            case "-":  {  // show the <textbox>, but 'disable' it
               var criteraTyps = document.getElementById('criteria_Typs');
               criteraTyps.selectedIndex = 0;

               document.getElementById('criteria_Box').removeAttribute('hidden'); 
               document.getElementById('criteria_Box').setAttribute("disabled",   true);
               break;
            }
             
            case "+": {  // select first 'criteria_Typs' item       
                                   // and fall thru to 'default' .. because no 'break'   
               var criteraTyps = document.getElementById('criteria_Typs');
               criteraTyps.selectedIndex = 0;
            }           
            default: {  // stringMode:  show the <textbox>, 'enable' it 
                    document.getElementById('criteria_Box').removeAttribute('hidden'); 
                    document.getElementById('criteria_Box').removeAttribute("disabled");  
                    document.getElementById('criteria_Box').value = cString; 
            }           
         }
      }


// === Sorter View/Categories ==================================================

rmFx_View.Sorter = function (mode) {
   
   var info = document.getElementById('sorter_Box').attributes["type"].value; /* 'view'|'criteria'*/
   var sortMode = mode.attributes["sorting"].value; /*sortMode 'up'|'down'*/

   var view_List = document.getElementById('view_List');
   var criteria_List = document.getElementById('criteria_List');
    
   if (info == 'view') {
      rmFxUtil.dump2Console ('viewSorting', "View sorting :" + info +"   sortMode:" + sortMode);
   
      var prefStr = rmFx_View.prefBuildStr();

      rmFx_View.clearThis(view_List);
      rmFx_View.clearThis(criteria_List);
  
      var cViews = prefStr.split(";>,")
  
      // sorting of 'view's 
      if (sortMode != null) {
         if (sortMode == 'up') cViews = cViews.sort();
         if (sortMode == 'down') cViews = cViews.sort().reverse();
        aViewEditor2Save = true;
      }

      var vCount = cViews.length;
      while ( vCount -- ) {
            var m1 = document.createElement("listitem");
            // apply parameters & insert before node 0
            if (cViews[vCount] != "") {
                
                var xx =cViews[vCount].split("=<");  // ex: FoxInfo=<DATE:TODAY;>,
                m1.setAttribute("label", xx[0]);        // FoxInfo
                m1.setAttribute("value", xx[1]);        // DATE:TODAY   
                m1.setAttribute("tooltiptext", xx[1] );

                m1.setAttribute("oncommand", "rmFx_View.ViewFocus(this);");

                if ( view_List.childNodes.length == 0 ) {
                     view_List.insertBefore(m1,null);
                }
                else {
                    view_List.insertBefore(m1,view_List.childNodes[0]);
                }
            }
        }
   }
   
   if (info == 'criteria') {
      var cView = view_List.selectedIndex;
      rmFxUtil.dump2Console ('viewSorting', "Criteria sorting for:" + cView + "   sortMode:" + sortMode);
      var criteria_List = document.getElementById('criteria_List');
      var vCount = criteria_List.childNodes.length;

      var sList = new Array(vCount);
      while ( vCount -- ) {
          sList[vCount] = criteria_List.childNodes[vCount].label;
      }

      // sorting of 'view's 
      if (sortMode != null) {
         if (sortMode == 'up') sList = sList.sort();
         if (sortMode == 'down') sList = sList.sort().reverse();
        aViewEditor2Save = true;
      }
   
      // write back to 'criteria_List'
      rmFx_View.clearThis(criteria_List);
   
      for (var i = 0; i < sList.length; i++){   
         var m1 = document.createElement("listitem");
           m1.setAttribute("label", sList[i]);
           m1.setAttribute("tooltiptext", stttCriteria);
         criteria_List.appendChild(m1);
      }    
       
      var aValues = sList.join(";");   
      view_List.childNodes[view_List.selectedIndex].value = aValues;  
      view_List.childNodes[view_List.selectedIndex].tooltipText = aValues;
       
      rmFxUtil.dump2Console ('viewSorting', "Criteria sorting :" + aValues + "   sortMode:" + sortMode);

       rmFx_ViewEdit.CriteriaEnter ('-');
    }
}


// ===  'View' Export/Send =====================================================
/**
 *  To 'export' the by 'View' pre-selected events (reminders OR todos/lists) 
 *  on the displayed 'Reminderfox List' are collected and pasted to output with
 *  'rmFx_ExportOrSend'
 *  The 'View' name is added as 'category' to each reminder
 * 
 *  @return   (null, 'info', reminderTyp, reminders)
 */
rmFx_View.ExportView = function () {

  var mode = (isReminderTabSelected() == true)  ? "Event" : "Todo";
   
   var reminders = new Array();
   var reminderFoxTodosArrayArg;
   var reminderTyp;
   var selectedTyp = 'info';

   // get reminders and todos model from the list window if possible - 
   // this allows you to get the latest categories even if not yet saved to 
   // the ics file yet
   
   // on 'reminders' or 'List/Todos' ??
   if (isReminderTabSelected() || isSubscribedCalendarTabSelected()){
      reminderTyp = 'reminder';
      
      var currentReminders = getCurrentReminderList();
   
      var treeChildren = document.getElementById("treechildren");

      var x = 0;
      
      for ( var item = 0; item < treeChildren.childNodes.length; item++ ) {
         var selectedTreeItem = treeChildren.childNodes[item];
         var id = selectedTreeItem.childNodes[0].getAttribute(REMINDER_ID_REF);
         
         for (var j=0; j < currentReminders.length; j++) {
            
            if ( currentReminders[j].id == id ) {
               reminders[x] = reminderFox_cloneReminderFoxEvent(currentReminders[j]);
               
               if (reminders[x].categories == null) {
                  reminders[x].categories = gRmFx_Views.cLabel[mode];
               } else {
                  reminders[x].categories += "," + gRmFx_Views.cLabel[mode];
               }
               x++;
            }
         }
      }
   } else {
      reminderTyp = 'todo';
      
      var tab =    document.getElementById("tabList").selectedItem;
      var listName = tab.getAttribute( "label");
      
      reminderFoxTodosArrayArg =  rmFx_View.GetallTodos();
   //   reminderFoxTodosArrayArg =  reminderFoxListWindow.reminderFox_getReminderTodos();
   //   reminders[0] = rmFx_View.EventsView(reminderFoxTodosArrayArg[listName], reminderTyp); 

      var selectedEvents = new Array();
      var j=0;
      for ( var n in reminderFoxTodosArrayArg[listName] ) {
         if (rmFx_ViewThis(reminderFoxTodosArrayArg[listName][n])) {

            selectedEvents[j] = reminderFox_cloneReminderFoxTodo(reminderFoxTodosArrayArg[listName][n]);

            if (selectedEvents[j].extraInfo == null) {
               selectedEvents[j].extraInfo = REMINDERFOX_EXTENDED + "LISTID:" + listName;
            } else {
               if (selectedEvents[j].extraInfo.indexOf(REMINDERFOX_EXTENDED + "LISTID") == -1) {
                  selectedEvents[j].extraInfo += "\\n" + REMINDERFOX_EXTENDED + "LISTID:" + listName;
               }
            }
            
            if (selectedEvents[j].categories == null) {
               selectedEvents[j].categories = gRmFx_Views.cLabel[mode];
            } else {
               selectedEvents[j].categories += "," + gRmFx_Views.cLabel[mode];
            }      
            j++;
         }
      }
      reminders[0] = selectedEvents;
   }
   
   rmFx_ExportOrSend (null, 'info' /*selectedTyp*/, reminderTyp, reminders)
}

/**
 *      Read 'VEVENT' and VTODO' from array 'events'
 *      into a single array 'selectedEvents', add the 'TAB' label 
 *      as a 'X-Reminderfox' item to the output
 * 
 */
rmFx_View.EventsView = function (events, reminderTyp) {   
   var selectedEvents = new Array();
   var j=0;
   for ( var n in events ) {
      if (rmFx_ViewThis(events[n])) {
         if (reminderTyp == 'todo') {
              selectedEvents[j] = reminderFox_cloneReminderFoxTodo(events[n]);
         } else {
              selectedEvents[j] = reminderFox_cloneReminderFoxEvent(events[n]);
         }

   //gW 2009-11-17
         if (selectedEvents[j].extraInfo == null) {
            selectedEvents[j].extraInfo = REMINDERFOX_EXTENDED + "LISTID:" + tabLabel;
         } else {
            if (selectedEvents[j].extraInfo.indexOf(REMINDERFOX_EXTENDED + "LISTID") == -1) {
               selectedEvents[j].extraInfo += "\\n" + REMINDERFOX_EXTENDED + "LISTID:" + tabLabel;
            }
         }

         
         if (selectedEvents[j].categories == null) {
            selectedEvents[j].categories = gRmFx_Views.cLabel[mode]; 
         } else {
            selectedEvents[j].categories += "," + gRmFx_Views.cLabel[mode];
         }      
         j++;
      }
   } 
   return selectedEvents;
}

/**
 *    Read from displayed dialog or -- if fails -- read the stored 'todos'   
 */
rmFx_View.GetallTodos = function () {
   var reminders;
   var reminderFoxTodosArrayArg;
   var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService();
   var windowManagerInterface = windowManager.QueryInterface(Components.interfaces.nsIWindowMediator);
   var reminderFoxListWindow = windowManagerInterface.getMostRecentWindow("window:reminderFoxEdit");

    if (reminderFoxListWindow) {
       reminders = reminderFoxListWindow.reminderFox_getReminderEvents();
       reminderFoxTodosArrayArg =  reminderFoxListWindow.reminderFox_getReminderTodos();
    }
    else {
       reminders = reminderFox_getReminderEvents();
       reminderFoxTodosArrayArg =  reminderFox_getReminderTodos();
    }
    return reminderFoxTodosArrayArg;
}

